package com.thoughtorigin.service {
import com.thoughtorigin.flux.Flux;

import com.thoughtorigin.meta.MetaOperator;
import com.thoughtorigin.module.ModuleLoader;
import com.thoughtorigin.util.Instantiator;

import flash.system.ApplicationDomain;
import flash.utils.Dictionary;
import flash.utils.getQualifiedClassName;

public class DictionaryServiceLocator implements ServiceLocator {

    private var _serviceDict: Dictionary;
    private var _flux: Flux;
    private var _instantiator: Instantiator;
    private var _metaOperator:MetaOperator;

    public function DictionaryServiceLocator() {
        _serviceDict = new Dictionary();
    }

    public function addService(service:Service):void {
        if(!service) return;
        _serviceDict[service.serviceName] = service;
    }

    public function locateService(serviceName:String, callback:Function):void {
        var service: Service = _serviceDict[serviceName];

        //if the services is not found, try looking in the flux
        if(!service && _flux) {
            service = Service(_flux.getProperty(serviceName));
            operateMetaData(service, callback);
            return;
        } else if(service && service.createNew) {
            service = Service(_instantiator.createByClassName(getQualifiedClassName(service), []));
            operateMetaData(service, callback)
            return;
        }
        callback.call(this, service);
    }

    private function operateMetaData(service:Service, callback:Function):void {
        _metaOperator.injectObject(service, function(e: Service): void {
            callback.call(this, service);
        });
    }

    public function get services(): Array {
        var retVal: Array = [];
        for(var key: String in _serviceDict) {
            retVal.push(_serviceDict[key]);
        }
        return retVal;
    }

    public function removeService(service:Service):void {
        if(!service) return;
        delete _serviceDict[service.serviceName];
    }

    public function set flux(value: Flux): void {
        _flux = value;
    }

    [Inject]
    public function set instantiator(value: Instantiator): void {
        _instantiator = value;
    }

    [Inject]
    public function set metaOperator(value: MetaOperator): void {
        _metaOperator = value;
    }

}
}